﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Eventable
{
    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public sealed class RegisterEventsAttribute : Attribute
    {
        public string[] NameEvents { get; private set; }
        
        public RegisterEventsAttribute(params string[] eventNames)
        {
            this.NameEvents = (eventNames ?? new string[0])
                .Where(s=>!s.IsEmpty())
                .ToArray();
        }
    }

    [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public sealed class RegisterOperationEventsAttribute : Attribute
    {
        public string[] NameOps { get; private set; }

        public RegisterOperationEventsAttribute(params string[] nameOperations)
        {
            this.NameOps = (nameOperations ?? new string[0])
                .Where(s => !s.IsEmpty())
                .ToArray();
        }
    }

    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public sealed class RegisterChangeEventsAttribute : Attribute
    {
        public string[] NameEvents { get; private set; }

        public RegisterChangeEventsAttribute(params string[] EventName)
        {
            this.NameEvents = (EventName ?? new string[0])
                .Where(s => !s.IsEmpty())
                .SelectMany(s => new string[] { s + "Changing", s + "Changed" })
                .ToArray();
        }
    }

    [Flags]
    public enum ChangeEvents
    {
        Changing = 1,
        Change = 2,
        Changed = 4,
        ChangingAndChanged = Changing | Changed,
        FullProperty = Changing | Change | Changed
    }

    [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
    public sealed class RegisterPropertyChangeAttribute : Attribute
    {
        public ChangeEvents ChangeEvents { get; private set; }

        public IEnumerable<string> GetNamesWith(string Name)
        {
            if (ChangeEvents.HasFlag(ChangeEvents.Changing))
                yield return Name + "Changing";
            if (ChangeEvents.HasFlag(ChangeEvents.Change))
                yield return Name + "_pE";
            if (ChangeEvents.HasFlag(ChangeEvents.Changed))
                yield return Name + "Changed";
        }

        public RegisterPropertyChangeAttribute(ChangeEvents ChangeEvents)
        {
            this.ChangeEvents = ChangeEvents;
        }
    }
}
